package com.qf.smartdevice.config;


import com.qf.smartdevice.mapper.MenuMapper;
import com.qf.smartdevice.pojo.Menu;
import com.qf.smartdevice.service.Impl.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.List;

@Configuration
@EnableWebSecurity
@EnableWebMvc
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    private MenuMapper menuMapper;
    private MyUserDetailService userDetailsService;
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    public void setMenuMapper(MenuMapper menuMapper) {
        this.menuMapper = menuMapper;
    }

    @Autowired
    public void setMyUserDetailService(MyUserDetailService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Autowired
    public void setPasswordEncoder(BCryptPasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//       如果需要拦截一些地址 最好现在前面设置好权限
        List<Menu> menuList = menuMapper.findAllRealMenus();

        menuList.forEach(menu -> {

            try {
                if (!StringUtils.isEmpty(menu.getPerms())) {
                    //设置每个地址需要的权限
                    http.authorizeRequests().antMatchers(menu.getUrl()).hasAnyAuthority(menu.getPerms());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

//        设置登录和退出接口地址
        http.authorizeRequests()
                .anyRequest().authenticated()//任意请求都需要认证，这样配置的原因是因为项目中地址非常多
                .and().formLogin().loginProcessingUrl("/login").successHandler(
                (req, res, authentication) -> {
                    res.sendRedirect("/index.html");
                }
        ).failureHandler((req, res, authentication) -> {
                    req.getSession().removeAttribute("pagelist");
                    res.sendRedirect("/login");
                }
        ).permitAll()//设置登录地址然后放行
                .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll();

        http.authorizeRequests().antMatchers("/layui/**", "/js/**").permitAll();//这些地址直接放行


    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //我们登陆的时候传递的是 admin admin ,数据库中是一个密文,但是这个密文怎么生成的,我们需要告诉 spring security
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
